﻿#region Copyright Statement
//  ------------------------------------------------------------------------------
//  
//    This file is part of The Streambolics Library.
//    Copyright © 2005-2009, Stephan Leclercq & Streambolics
//    All rights reserved.
//  
//    The Streambolics Library is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//  
//    The Streambolics Library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//  
//    You should have received a copy of the GNU General Public License
//    along with Streambolics; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//  
//  ------------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Streambolics.Hp41s
{
    /// <summary>
    ///     A number representing a numbered or single-lettered slot for registers, 
    ///     flags or labels.
    /// </summary>
    /// <remarks><para>
    ///     Contrary to the internal HP-41C representation, letter references are
    ///     negative instead of in the range 110-127.
    /// </para></remarks>

    public static class Reference
    {
        public const int Offset = 52;

        public const int a = -52;
        public const int b = -51;
        public const int c = -50;
        public const int d = -49;
        public const int e = -48;
        public const int f = -47;
        public const int g = -46;
        public const int h = -45;
        public const int i = -44;
        public const int j = -43;
        public const int k = -42;
        public const int l = -41;
        public const int m = -40;
        public const int n = -39;
        public const int o = -38;
        public const int p = -37;
        public const int q = -36;
        public const int r = -35;
        public const int s = -34;
        public const int t = -33;
        public const int u = -32;
        public const int v = -31;
        public const int w = -30;
        public const int x = -29;
        public const int y = -28;
        public const int z = -27;
        public const int A = -26;
        public const int B = -25;
        public const int C = -24;
        public const int D = -23;
        public const int E = -22;
        public const int F = -21;
        public const int G = -20;
        public const int H = -19;
        public const int I = -18;
        public const int J = -17;
        public const int K = -16;
        public const int L = -15;
        public const int M = -14;
        public const int N = -13;
        public const int O = -12;
        public const int P = -11;
        public const int Q = -10;
        public const int R = -9;
        public const int S = -8;
        public const int T = -7;
        public const int U = -6;
        public const int V = -5;
        public const int W = -4;
        public const int X = -3;
        public const int Y = -2;
        public const int Z = -1;

        public static string ToStr (int n)
        {
            if (n >= 0)
            {
                return String.Format ("{0:D2}", n);
            }
            else if (n >= A)
            {
                return ((char)(n - A + (int)'A')).ToString ();
            }
            else
            {
                return ((char)(n - a + (int)'a')).ToString ();
            }
        }

        /// <summary>
        ///     Interprets a string as a reference.
        /// </summary>
        /// <param name="p">
        ///     The string to parse
        /// </param>
        /// <returns>
        ///     The corresponding reference.
        /// </returns>

        public static int Parse (string p)
        {
            if (p.Length == 1)
            {
                char c = p[0];
                if (c >= 'A' && c <= 'Z')
                {
                    return (int)c - (int)'A' + A;
                }
                if (c >= 'a' && c <= 'z')
                {
                    return (int)c - (int)'a' + a;
                }
            }
            return p.ToInteger();
        }
    }
}
